<template>
    <div class="lg-massage-box__wrapper">
        <div
            :class="['lg-massage-box', {'lg-massage--visible': visible}, {[customClass]:customClass}]"
        >
            <i class="lg-massage__close iconfont icon-simplicityClose" v-if="showClose" @click="handleAction('close')"/>
            <div class="lg-massage--header" :style="centerStyle('text')">{{title}}</div>
            <div class="lg-massage--content" :style="centerStyle()">
                <i v-if="showIcon && messageType != 'alert'" :class="['iconfont', getStatusIcon(), {[type]: type}, {success: iconClass}]"></i>
                <div ref="VNodeRefs" v-if="message && typeof message == 'object'"></div>
                <span v-else-if="!dangerouslyUseHTMLString">{{message}}</span>
                <div v-else v-html="message"></div>
            </div>
            <div class="lg-massage--footer" :style="centerStyle('text')">
                <lg-Button @click="handleAction('cancel')" :round="roundButton" v-if="showCancelButton && messageType != 'alert'" :class="{[cancelButtonClass]: cancelButtonClass}">{{cancelButtonText}}</lg-Button>
                <lg-Button @click="handleAction('confirm')" :round="roundButton" v-if="showConfirmButton" type="primary" :class="{[confirmButtonClass]: confirmButtonClass}">{{confirmButtonText}}</lg-Button>
            </div>
        </div>
        <div :class="['lg-massage__overlay', {pointer: closeOnClickModal}]" @click="closeOnClickModal && handleAction('overlay')"></div>
    </div>
</template>

<script>
import lgButton from '@/components/Basic/button'
export default {
    name: "lgMessageBox",
    components: {
        lgButton
    },
    data(){
        return {
            visible:false,
            title:'',
            message:'', // String ang VNode使用VNode方式渲染
            center: false, // 是否居中显示
            promise:null,
            closeOnClickModal: true, // 是否点击遮罩层关闭modal
            showClose: true,  // 是否显示关闭按钮
            messageType: '', // messageBox的类型
            type: 'warning', // 消息类型，用于显示图标
            iconClass: '', // 自定义图标的类名，会覆盖 type
            showIcon: true, // 是否显示图标
            customClass: '', // MessageBox 的自定义类名
            beforeClose: null, // MessageBox 关闭前的回调，会暂停实例的关闭
            lockScroll: true, // 是否在 MessageBox 出现时将 body 滚动锁定
            showCancelButton: true,	// 是否显示取消按钮
            showConfirmButton: true,	// 是否显示确定按钮
            cancelButtonText: '取消',	// 取消按钮的文本内容
            confirmButtonText: '确定',	// 确定按钮的文本内容
            cancelButtonClass: '',	// 取消按钮的自定义类名
            confirmButtonClass: '',	// 确定按钮的自定义类名
            closeOnPressEscape: true,	// 是否可通过按下 ESC 键关闭 MessageBox
            roundButton: false, // 是否使用圆角按钮
            closeOnHashChange: false, // 是否在 hashchange 时关闭 MessageBox
            callback: null, // 若不使用 Promise，可以使用此参数指定 MessageBox 关闭后的回调
            dangerouslyUseHTMLString: false, // 是否使用html标签
            doneStatus: true,
            action: ''
        }
    },
    watch: {
        visible: {
            handler (newVal) {
                this.hiddenScroll()
                if (newVal) {
                    this.onPressEscape()
                    this.onHashChange()
                    if (this.message && typeof this.message == 'object') {
                        this.__patch__(this.$refs.VNodeRefs, this.message, false, true) 
                    }
                }
            },
            immediate: true
        },
    },
    methods: {
        centerStyle(type) {
           if (type == 'text') {
              return this.center && 'text-align: center;' || ''
           } else {
              return this.center && 'justify-content: center;' || ''
           }
        },
        onPressEscape () {
            if (!this.closeOnPressEscape) return false
            this.$nextTick(() => {
                document.addEventListener('keyup', this.onKeyup, true)
            })
        },
        onHashChange () {
            if (!this.closeOnHashChange) return false
            this.$nextTick(() => {
                document.addEventListener('hashchange', this.handleAction('hashchange'), true)
            })
        },
        hiddenScroll () {
            let body = document.body
            if (this.lockScroll && this.visible) {
                body.style.overflow = 'hidden'
            } else {
                let body = document.body
                body.style.overflow = ''
            }
        },
        visibleTouch() {
            setTimeout(()=> {
              this.visible = true;
            }, 1)
            return new Promise((resolve, reject) =>{
                this.promise = {resolve, reject};
            });
        },
        done() {
          this.doneStatus = false
          this.handleAction(this.action)
        },
        //正确或取消方法，父组件使用.then或catch方法接收
        handleAction(action){
            this.action = action
            if(typeof this.beforeClose == 'function' && this.doneStatus){
                this.beforeClose(action, this, this.done)
                return false
            }
            this.visible = false;
            if(action == 'confirm'){
                this.promise && this.promise.resolve(action);
            }else{
                this.promise && this.promise.reject(action);
            }
            typeof this.callback == 'function' && this.callback(action, this)
            setTimeout(() => { this.doneStatus = true }, 300)
        },
        getStatusIcon(){
            let type = ''
            switch(this.type) {
                case 'info':
                    type = 'info'
                break;
                case 'warning':
                    type = 'warning'
                break;
                case 'error':
                    type = 'error'
                break;
                default:
                    type = 'success'
                break;
            }
            if (this.iconClass) {
                return this.iconClass.includes('icon-') ? this.iconClass: `icon-${this.iconClass}`
            }
            return `icon-${type}`
        },
        onKeyup (e) {
            if (e.keyCode == 27) {
                this.handleAction('overlayEscape')
            }
        },
    },
    destroyed() {
        this.closeOnPressEscape && document.removeEventListener('keyup', this.onKeyup, true)
        this.closeOnHashChange && document.removeEventListener('hashchange', this.handleAction('hashchange'), true)
    }
}
</script>

<style lang="less" scoped>
.lg-massage-box__wrapper{
    .lg-massage-box {
        position: fixed;
        left: 50%;
        width: 400px;
        top: 40%;
        transform: translateX(-50%);
        z-index: 2001;
        height: auto;
        border-radius: 5px;
        background: #fff;
        visibility: hidden;
        -webkit-backface-visibility: hidden;
        -moz-backface-visibility: hidden;
        backface-visibility: hidden;
        opacity: 0;
        -webkit-transition: all 0.3s;
        -moz-transition: all 0.3s;
        transition: all 0.3s;
        .lg-massage--content {
            padding: 10px 15px 10px;
            height: auto;
            color: #606266;
            font-size: 14px;
            line-height: 24px;
            display: flex;
            align-items: flex-start;
            justify-content: flex-start;
            i{
                margin-right: 10px;
                margin-left: 3px;
                font-size: 28px;
            }
            span{
                line-height: 24px;
            }
        }
        .lg-massage--header{
            margin: 0;
            font-size: 18px;
            color: #555;
            line-height: 1;
            padding: 15px 15px 10px;
        }
        .lg-massage--footer{
            padding: 10px 15px 15px;
            text-align: right;
            /deep/ .lg-button{
                padding: 7px 15px;
                font-size: 12px !important;
            }
            /deep/ .default{
                color: #606266
            }
        }
        .lg-massage__close{
            position: absolute;
            right: 15px;
            top: 15px;
            cursor: pointer;
            color: #999;
            font-size: 16px;
        }
    }
    .lg-massage__overlay {
        position: fixed;
        width: 100%;
        height: 100%;
        visibility: hidden;
        top: 0;
        left: 0;
        z-index: 2000;
        opacity: 0;
        background: rgba(0,0,0,.5);
        -webkit-transition: all 0.4s;
        -moz-transition: all 0.4s;
        transition: all 0.4s;
        user-select: none;
    }
    .lg-massage--visible{
        opacity: 1;
        visibility: visible;
        -webkit-backface-visibility: visible;
        -moz-backface-visibility: visible;
        backface-visibility: visible;
        & ~ .lg-massage__overlay {
            opacity: 1;
            visibility: visible;
            -webkit-backface-visibility: visible;
            -moz-backface-visibility: visible;
            backface-visibility: visible;
        }
    }
    .info{
       color: #909399
    }
    .warning{
       color: #e6a23c
    }
    .error{
       color: #f56c6c
    }
    .success{
       color: #67c23a
    }
}
.pointer{
    cursor: pointer;
}
</style>